#define _CRT_SECURE_NO_WARNINGS
// ↑ 将本行在代码放在第一行可以避免 scanf的报错问题（仅在VS编译器里）
//【初阶篇】77.指针_指针和指针的类型
//【初阶篇】78.休息
//【初阶篇】79.指针_野指针，指针运算
//【初阶篇】80.休息
//【初阶篇】81.指针和数组
#include<stdio.h>
#include<string.h>
int my_strlen(char* str)
{
	int count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int my_strlen2(char* str)
{
	char* start = str;
	while (*str != '\0')
	{
		str++;
	}
	return (str - start);
}
int main()
{
	//指针
	{
		int a = 1;	  //  a -【变量】
		int* pa = &a; // pa - 变量的【指针|指针变量】
		printf("a=%d; pa=%p\n", a, pa);//32位机器（x86） 8位16进制  ，64位机器 16位16进制 
		double* pb = NULL;
		char* pc = NULL;
		printf("%zu\n", sizeof(pa));
		printf("%zu\n", sizeof(pb));
		printf("%zu\n", sizeof(pc));
	}
	
	//指针类型的意义
	{
		int a = 0x11223344;
		int* pa = &a; 
		*pa = 0;// -> a = 00000000
		char* pc = (char * )& a;
		*pc = 0;// -> a = 11223300
		//指针类型决定指针在被解引用时访问几个字节，整形访问4个字节，字符类型访问1个字节

		printf("pa = %p\n", pa);
		printf("pa+1 = %p\n", pa + 1);

		printf("pc = %p\n", pc);
		printf("pc+1 = %p\n", pc + 1);
		//指针类型决定了指针+1|-1操作时跳过几个字节
	}

	//野指针
	{
		//无明确指向
			//int* p;//p没有初始化，会放随机值，
			//*p = 10;//在这里赋值会把值赋给一个随机地址，即非法访问内存

		//越界访问
			//int arr[10] = { 0 };
			//int* p = arr;
			//int i = 0;
			//for (i = 0; i <= 10; i++)
			//{
			//	*p = i;
			//	p++;//如果循环加到10时访问越界，变成野指针
			//}
	}	
	//指针+|-整数
	{
		int arr[10];
		int* p = arr;
		int i = 0;
		for (i = 0; i < 10; i++)
		{
			*p = i;//解引用，访问数组元素地址，给数组元素赋值
			printf("arr[%d]=%d,*p= %p\n",i, *(p+i), (p+i));
			//p++;//指针+|-整数运算
		}
	}
	//指针-指针 得到的是指针和指针间元素个数有符号（指向同一块空间的指针才能相减）
	{
		{
			int arr[10] = { 0 };
			int* p1 = &arr[0];
			int* p2 = &arr[9];
			int r = p2 - p1;
			printf("p2 - p1=%d\n", r);
		}
		
		//实际用法
		{
			int len = my_strlen2("abcdef");
			printf("%d\n", len);
		}

	}
	//指针的关系运算(比较大小)
	{
		//允许指向数组元素的指针和数组元素之后的指针比较，不运行向前比较
	}

	return 0;
}

//77.指针_指针和指针的类型
	//1.指针：是内存中最小单元(1字节|byte)的编号，
		//1.指针本质上是地址
		//2.口语中的说的指针，通常指指针变量
		//3.指针大小在32位机器上是4个字节 ；64位机器上是8个字节
			//因为1bit能表达2个数1/0. 32位机器有32个地址线，即接受1个地址时需要用32bit=4byte（1byte = 8bit）的空间存储
			//同理64位机器则需要8个字节空间存储地址
		//4.由下可以得出32位机器上 16进制的8位地址，等效于8*（4位2进制），等效于8*4bit，等于32bit，即32位机器地址/指针大小为4字节的原因
			//1. 十六进制（HEX）、十进制（DEC）、八进制（OCT）和二进制（BIN）|//0x代表16进制|0O代表8进制|0B代表二进制|十进制不用前缀
			//2. 1个16进制位可以表示4个二进制位，即0-f等效二进制 
			//3. 0~7  : 0-0000 1-0001 2-0010 3-0011 4-0100 5-0101 6-0110 7-0111 
			//4. 8~15 : 8-1000 9-1001 a-1010 b-1011 c-1100 d-1101 e-1110 f-1111
	//2.指针的类型：不同类型指针在解引用、移位运算时影响的字节数与指针变量类型有关
		//1. *要区分指针变量占用内存，和指针类型对指针操作影响内存的大小是两个概念 
		//2. 指针类型决定指针在被解引用时访问几个字节，也决定在指针＋|－位操作时跳过的字节数
//79.指针_野指针、指针运算
	//1.野指针：指针指向的位置不可知、随机、没有明确限制
		// 避免越界、提前初始化、避免局部变量地址、检查指针有效性
	//2.指针运算：//指针+|-整数 | //指针-指针 | //指针的关系运算
//81.指针和数组
	//1.指针变量：存放地址
	//2.数组：一组相同类型的元素集合
	//但数组可以通过指针来访问